//
// Created by chen on 2023/6/22.
//

#include <sstream>
#include "contestSystem.h"


Contestant::Contestant(int id, std::string name) {
    this->c_id = id;
    this->c_name = name;
}

ContestSystem::ContestSystem() {

}

bool MyCompare::operator()(Contestant &c1, Contestant &c2) {
    return c1.score > c2.score;
}

void ContestSystem::showMenu() {
    cout << "*******************************" << endl;
    cout << "********欢迎参加演讲比赛**********" << endl;
    cout << "********1、开始演讲比赛***********" << endl;
    cout << "********2、查看往届记录***********" << endl;
    cout << "********3、清空往届记录***********" << endl;
    cout << "********0、退出比赛系统***********" << endl;
    cout << "********************************" << endl;
}

// 打印输出当前数组中元素
void printVector(vector<Contestant> v){
    for (vector<Contestant>::iterator it= v.begin(); it!= v.end(); ++it) {
        cout << "编号:" << it->c_id <<", 姓名:" << it->c_name << endl;
    }
}

// 打印单个参赛者的回调函数 无分数
void printCallBack(Contestant c){
    cout << "编号:" << c.c_id <<", 姓名:" << c.c_name << endl;
}

void printVector2(int a){
    cout << a << " ";
}

// 打印单个参赛者的回调函数 有打分
void printCallBack2(Contestant c){
    cout << "编号:" << c.c_id <<", 姓名:" << c.c_name << ", 打分:";
    for_each(c.scores.begin(), c.scores.end(), printVector2);
    cout << endl;
}

// 打印单个参赛者的回调函数 有平均分
void printCallBack3(Contestant c){
    cout << "编号:" << c.c_id <<", 姓名:" << c.c_name << ", 分数:" << c.score << endl;
}

// 给参赛选手随机打分
void setScore(Contestant & c){
    c.scores.clear();
    for (int i = 0; i < 10; ++i) {
        int score = rand() % 40 + 60;
        c.scores.push_back(score);
    }
}

// 根据传入的数组计算平均数
float calcAverage(deque<int> d){
    float size = d.size();
    int sum = 0;
    for (deque<int>::iterator it= d.begin(); it!= d.end() ; ++it) {
        sum += *it;
    }
    return sum / size;
}

void calcScore(Contestant & c){
    c.score = -1;
    sort(c.scores.begin(), c.scores.end());
    c.scores.pop_back();
    c.scores.pop_front();
    c.score = calcAverage(c.scores);
}

// 将比赛结果储存到csv文件中
void saveToCsv(vector<Contestant> winner){
    ofstream ofs;
    ofs.open("result.csv", ios::out | ios::app);
    for (int i = 0; i < 3; ++i) {  // 只写入前三位获胜者
        ofs << winner[i].c_id << ",";
        ofs << winner[i].score << ",";
    }
    ofs << "\n";
    ofs.close();
    cout << "比赛结果已成功写入文件" << endl;
}

void ContestSystem::startContest() {
    vector<Contestant> allContestant;  // 储存12个参赛选手
    string nameSeed = "ABCDEFGHIJKL";
    for (int i = 0; i < 12; ++i) {
        string name = "选手";
        name += nameSeed[i];
        Contestant temp(10001+i, name);
        allContestant.push_back(temp);
    }
    cout << "12位参赛者已经初始化, 分别为:" << endl;
    for_each(allContestant.begin(), allContestant.end(), printCallBack);
    cout << "输入任意键为参赛者随机分组" << endl;
    string temp;
    cin >> temp;
    random_shuffle(allContestant.begin(), allContestant.end());
    cout << "分组结果为:" << endl;
    vector<Contestant> group1(allContestant.begin(), allContestant.begin()+6);  // 第一组
    vector<Contestant> group2(allContestant.begin()+6, allContestant.end());  // 第二组
    cout << "第一组:" << endl;
    for_each(group1.begin(), group1.end(), printCallBack);
    cout << "第二组:" << endl;
    for_each(group2.begin(), group2.end(), printCallBack);
    cout << "输入任意键查看第一轮比赛结果" << endl;
    cin >> temp;
    srand((unsigned)time(nullptr));
    for_each(group1.begin(), group1.end(), setScore);
    for_each(group2.begin(), group2.end(), setScore);
    cout << "第一组:" << endl;
    for_each(group1.begin(), group1.end(), printCallBack2);
    cout << "第二组:" << endl;
    for_each(group2.begin(), group2.end(), printCallBack2);

    for_each(group1.begin(), group1.end(), calcScore);
    for_each(group2.begin(), group2.end(), calcScore);
    cout << "删除最高分和最低分后:" << endl;
    cout << "第一组:" << endl;
    for_each(group1.begin(), group1.end(), printCallBack2);
    cout << "第二组:" << endl;
    for_each(group2.begin(), group2.end(), printCallBack2);
    cout << "排名:" << endl;
    sort(group1.begin(), group1.end(), MyCompare());
    sort(group2.begin(), group2.end(), MyCompare());
    cout << "第一组:" << endl;
    for_each(group1.begin(), group1.end(), printCallBack3);
    cout << "第二组:" << endl;
    for_each(group2.begin(), group2.end(), printCallBack3);
    vector<Contestant> finalContestant(group1.begin(), group1.begin()+3);  //决赛选手组
    vector<Contestant>::iterator it = group2.begin();
    finalContestant.push_back(*it++);
    finalContestant.push_back(*it++);
    finalContestant.push_back(*it++);
    cout << "决赛选手组:" << endl;
    for_each(finalContestant.begin(), finalContestant.end(), printCallBack3);
    for_each(finalContestant.begin(), finalContestant.end(), setScore);
    cout << "输入任意键查看决赛结果" << endl;
    cin >> temp;
    cout << "决赛打分" << endl;
    for_each(finalContestant.begin(), finalContestant.end(), printCallBack2);
    for_each(finalContestant.begin(), finalContestant.end(), calcScore);
    cout << "决赛删除最高分和最低分:" << endl;
    for_each(finalContestant.begin(), finalContestant.end(), printCallBack2);
    cout << "决赛排名:" << endl;
    sort(finalContestant.begin(), finalContestant.end(), MyCompare());
    for_each(finalContestant.begin(), finalContestant.end(), printCallBack3);
    saveToCsv(finalContestant);
}

void ContestSystem::viewHistory() {
    ifstream ifs;
    ifs.open("result.csv", ios::in);
    if(!ifs.is_open()){
        cout << "文件打开失败!" << endl;
        return;
    }
//    int id;
//    float score;
//    while (ifs >> id && ifs >> score){
//        cout << "编号:" << id << ", 分数:" << score << endl;
//    }
    string buf;
    istringstream sin;
    vector<string> temp;
    string word;
    while (getline(ifs, buf)){
        sin.clear();
        sin.str(buf);
        temp.clear();
        while (getline(sin, word, ',')){
            temp.push_back(word);
        }
        // 可以在buf中find,定位到,的位置 然后利用substr截取字符串
        for (vector<string>::iterator it = temp.begin(); it != temp.end(); ++it) {
            cout << "编号:" << *it++ << ", 分数:" << *it << endl;
        }
        cout << "--------------------分界线----------------------" << endl;
    }
    ifs.close();
}

void ContestSystem::clearHistory() {
    ofstream ofs;
    ofs.open("result.csv", ios::trunc);
    ofs.close();
    cout << "已清空记录文件" << endl;
}

void ContestSystem::exitContest() {
    cout << "欢迎下次使用！" << endl;
    exit(0);
}

